package com.polaris.live.ui.game

import android.content.Context
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import com.blankj.utilcode.util.ActivityUtils
import com.polaris.live.common.cacha.CacheUtil
import com.polaris.live.common.cacha.UserManager
import com.polaris.live.common.manager.CoroutineScopeManager
import com.polaris.live.common.util.JsonUtils
import com.polaris.live.common.util.ViewUtils
import com.polaris.live.net.gameService
import com.polaris.live.resp.back_resp.GameGroupVoResp
import com.polaris.live.resp.back_resp.GameVo
import com.polaris.live.resp.event.GameDotUpdateEvent
import com.polaris.live.resp.event.GameListEvent
import com.polaris.live.resp.go_resp.GameActiveBean
import com.polaris.live.utils.CommonUtils
import com.polaris.live.utils.route.RoutePath
import com.polaris.live.utils.route.Router
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import com.polaris.live.common.constant.AppConst
import org.greenrobot.eventbus.EventBus

/**
 * GameUtils
 * @author Created by 天晴 on 2024/1/18 18:00
 * @since 1.0.0
 **/
object GameUtils {

    const val FULL_SCREEN = "3" //全屏
    const val FULL_SCREEN2 = "0"//yomi游戏全屏

    const val HALF_SCREEN = "2" //半屏
    const val HALF_SCREEN2 = "1" //yomi游戏半屏

    private var meList: List<GameGroupVoResp>? = null //我的游戏列表
    private var liveList: List<GameGroupVoResp>? = null //直播間游戏列表
    private var hotList: List<GameVo>? = null //热门游戏列表
    var gameRun = false //游戏是否在运行
    fun setHotGameList(list: List<GameVo>?) {
        this.hotList = list
    }

    fun getHotGameList(): List<GameVo>? {
        return hotList
    }

    fun setMeCacheGameList(list: List<GameGroupVoResp>?) {
        meList = list
        if (!list.isNullOrEmpty()) {
            hotList = list[0].list
            EventBus.getDefault().post(GameListEvent(true))
            EventBus.getDefault().post(GameDotUpdateEvent(getGameDotCount()))
        }
    }

    fun getMeCacheGameList(): List<GameGroupVoResp>? {
        return meList
    }

    fun setLiveCacheGameList(list: List<GameGroupVoResp>?) {
        liveList = list
    }

    fun getLiveCacheGameList(): List<GameGroupVoResp>? {
        return liveList
    }

    /**
     * 获取红点列表
     */
    fun getDotList(): List<Long> {
        return meList?.flatMap { it.dotGameIDS.orEmpty() }?.distinct() ?: emptyList()

    }

    /**
     * 游戏红点数
     */
    private fun getGameDotCount(): Int {
        val dotList = getDotList()  //需要展示的游戏红点
        val dotEnterList = CacheUtil.getEnterDot()  //已经进入过的红点
        val count = dotList.count { dot ->
            dotEnterList.none { it == dot }
        }
        return count
    }

    /**
     * 获取是否显示红点
     */
    fun getShowDotByGameId(gameId: Long): Boolean {
        val ids = getDotList()
        return ids.any { it == gameId }
    }

    /**
     * 获取是否显示排行榜弹窗
     */
    fun getShowWinPop(liveId: Long): Boolean {
        val id = ShowGameWinPopLiveIds.find { it == liveId }
        if (id != null) { //这个房间弹过了
            return false
        }
        val safeLevel = UserManager.getUser().flag?.safeLevel
        val safeType = UserManager.getUser().flag?.safeType
        val isSafeUser = CommonUtils.isSafeUser(safeLevel, safeType)
        if (!isSafeUser) { //安全用户不弹
            return false
        }
        return if (!liveList.isNullOrEmpty()) {
            val createTime = UserManager.getUser().createTime ?: 0
            val serverTime = CacheUtil.getServerTime()
            if (serverTime - createTime > MAX_POP_TIME) { //大于7天用户
                val lastPopTime = CacheUtil.getLastGameWinPopTime()
                serverTime - lastPopTime > MAX_POP_TIME  //24小时一次
            } else {
                CacheUtil.getManyGameWinPopTime().let { list ->
                    list.isEmpty() ||
                            (serverTime - list.last() > MAX_POP_TIME) ||
                            (serverTime - list.getOrElse(list.size - 2) { 0 } > MAX_POP_TIME)
                }

            }
        } else {
            false
        }
    }

    fun putShowLiveId(liveId: Long) {
        ShowGameWinPopLiveIds.add(liveId)
    }

    /**
     * 存进入并弹窗过的LiveIds
     */
    private val ShowGameWinPopLiveIds = mutableListOf<Long>()

    private const val MAX_POP_TIME = 24 * 60 * 60 * 1000  //最大弹窗24小时弹窗一次

    const val MAX_LAST_POP_TIME = 40 * 1000L  //赢豆排行榜弹窗延时

    const val MAX_RETRY_COUNT = 3

    private const val RETRY_TIME = 10000L

    var retryCount = 0 //重试次数

    private var gameListJob: Job? = null

    fun getFirstGameList() {
        gameListJob?.cancel()
        gameListJob = CoroutineScopeManager.ioScope.launch {
            try {
//                getNetGameList()
            } finally {
                if (gameListJob == coroutineContext[Job]) {
                    gameListJob = null
                }
            }
        }
    }

    private suspend fun getNetGameList() {
        runCatching {
            gameService.getGameList(GameFromType.ME)
        }.onSuccess {
            if (it.isSuccess()) {
                setMeCacheGameList(it.getResponseData())
            } else {
                retryGameList()
            }
        }.onFailure {
            retryGameList()
        }
    }

    private fun retryGameList() {
        if (retryCount < MAX_RETRY_COUNT) {
            retryCount++
            gameListJob?.cancel()
            gameListJob = CoroutineScopeManager.ioScope.launch {
                try {
                    delay(RETRY_TIME)
//                    getNetGameList()
                } finally {
                    if (gameListJob == coroutineContext[Job]) {
                        gameListJob = null
                    }
                }
            }
        }
    }

    /**
     * 游戏唤起
     */
    private fun gameActive(gameId: Long, roomId: Long?) {
        CoroutineScopeManager.ioScope.launch {
            gameService.getGameActive(GameActiveBean(gameId, roomId))
        }
    }

    fun showGameFragment(
        context: Context,
        data: GameVo,
        roomId: String = "",
    ) {
        val finalContext = if (context is AppCompatActivity) {
            context
        } else {
            val aliveActivity = ViewUtils.getAliveTopActivity()
            if (aliveActivity is AppCompatActivity) {
                aliveActivity
            } else {
                null
            }
        }
        if (finalContext == null) {
            return
        }

        if (gameRun) {
            val fr: Fragment? = finalContext.supportFragmentManager.findFragmentByTag("game")
            if (fr != null) {
                return
            }
        }
        gameActive(data.gameID, roomId.toLongOrNull())
        //处理红点
        CacheUtil.setEnterDot(data.gameID)
        EventBus.getDefault().post(GameDotUpdateEvent(getGameDotCount()))
        val fragmentManager = finalContext.supportFragmentManager

        val screen = if (data.providerType == AppConst.GameType.YOMI) HALF_SCREEN2 else HALF_SCREEN

        GameWebFragment().apply {
            val bd = Bundle()
            bd.putParcelable("gameVo", data)
            bd.putString("gameMode", screen)
            bd.putString("roomId", roomId)
            arguments = bd
        }.show(fragmentManager, "game")
    }

    /**
     * 关闭游戏的fragment
     */
    fun dismissGameFragment(context: Context) {
        val finalContext = if (context is AppCompatActivity) {
            context
        } else {
            val aliveActivity = ViewUtils.getAliveTopActivity()
            if (aliveActivity is AppCompatActivity) {
                aliveActivity
            } else {
                null
            }
        }
        if (finalContext == null) {
            return
        }
        if (gameRun) {
            val fr: Fragment? = finalContext.supportFragmentManager.findFragmentByTag("game")
            if (fr != null && fr is GameWebFragment) {
                fr.dismiss()

                try {
                    finalContext.supportFragmentManager.beginTransaction().apply {
                        remove(fr)
                        commitAllowingStateLoss()
                    }
                } catch (_: Throwable) {
                }
            }
        }
    }

    /**
     * 显示全屏游戏页面
     */
    fun showGameActivity(
        context: Context,
        data: GameVo,
        roomId: String = "",
    ) {
        if (gameRun) {
            if (ActivityUtils.getTopActivity() is WebGameActivity) {
                return
            }
        }
        gameActive(data.gameID, roomId.toLongOrNull())
        //处理红点
        CacheUtil.setEnterDot(data.gameID)
        EventBus.getDefault().post(GameDotUpdateEvent(getGameDotCount()))

        val screen = if (data.providerType == AppConst.GameType.YOMI) FULL_SCREEN2 else FULL_SCREEN

        Router.builder(RoutePath.GAME_WEB_GAME_ACTIVITY)
            .withAny("gameVo", data)
            .withString("gameMode", screen)
            .withString("roomId", roomId)
            .navigation(context)
    }

    /**
     * 显示并且检查游戏显示
     */
    fun showAndCheckGameFragment(context: Context, userId: Long?, payload: String?) {
        if (payload == null || userId == null) {
            return
        }

        try {
            val gameId = JsonUtils.readPrimitiveFromJsonObject(payload, "gameId")?.toLongOrNull()
            if (gameId != null && gameId > 0) {
                val roomId = userId.toString()
                val gameData = GameUtils.getLiveCacheGameList()
                    ?.flatMap { it.list }
                    ?.find { it.gameID == gameId }

                gameData?.let {
                    showGameFragment(
                        context,
                        it,
                        roomId = roomId
                    )
                }
            }
        } catch (_: Exception) {
        }
    }

    fun finish() {
        gameRun = false
        lists.forEach {
            it.gameClose()
        }
    }

    fun start() {
        gameRun = true
        lists.forEach {
            it.gameStart()
        }
    }

    private val lists = mutableListOf<GameStateListener>()
    fun addGameStateListener(listener: GameStateListener) {
        lists.add(listener)
    }

    fun removeGameStateListener(listener: GameStateListener) {
        lists.remove(listener)
    }

    fun release() {
        meList = null
        liveList = null
        hotList = null
        gameRun = false
    }

    /**
     * 游戏界面监听
     */
    interface GameStateListener {

        fun gameStart()
        fun gameClose()

    }
}